Imports System.Windows.Forms
Imports Vintasoft.Imaging.Codecs.Tiff

Public Partial Class TagInfoForm
	Inherits Form

	#Region "Fields"

	Private _tiffPage As TiffPage
	Private _tiffLvg As ListViewGroup

	#End Region


	#Region "Constructor"

	Public Sub New(tiffPage As TiffPage)
		_tiffPage = tiffPage

		InitializeComponent()

		If tiffPage IsNot Nothing Then
			' Tiff Tags
			Dim lvg As ListViewGroup = Nothing
			If tiffPage.Tags.Count > 0 Then
				lvg = tagInfoList.Groups.Add("TiffTags", "Tiff Tags")
				_tiffLvg = lvg
			End If
			For Each tag As TiffTag In tiffPage.Tags
				AddTagDataToList(lvg, tag)
			Next

			' EXIF Tags
			lvg = Nothing
			If tiffPage.Tags.Count > 0 Then
				lvg = tagInfoList.Groups.Add("ExifTags", "EXIF Tags")
			End If
			For Each tag As TiffTag In tiffPage.ExifTags
				AddTagDataToList(lvg, tag)
			Next

			' GPS Tags
			lvg = Nothing
			If tiffPage.Tags.Count > 0 Then
				lvg = tagInfoList.Groups.Add("GpsTags", "GPS Tags")
			End If
			For Each tag As TiffTag In tiffPage.GpsTags
				AddTagDataToList(lvg, tag)
			Next

			' Interoperability Tags
			lvg = Nothing
			If tiffPage.Tags.Count > 0 Then
				lvg = tagInfoList.Groups.Add("InteroperabilityTags", "Interoperability Tags")
			End If
			For Each tag As TiffTag In tiffPage.InteroperabilityTags
				AddTagDataToList(lvg, tag)
			Next
		End If
	End Sub

	#End Region


	#Region "Methods"

	#Region "Close dialog"

	Private Sub CloseButton_Click(sender As Object, e As EventArgs)
		Close()
	End Sub

	#End Region


	#Region "Add information about tag to list"

	Private Sub AddTagDataToList(lvg As ListViewGroup, tag As TiffTag)
		Dim lvi As ListViewItem = tagInfoList.Items.Add(tag.Name)
		lvi.Group = lvg
		Dim tagData As [Object] = tag.Data
		lvi.SubItems.Add(tagData.[GetType]().Name)
		lvi.SubItems.Add(tag.IsReadonly.ToString())
		lvi.Tag = tag
		If tagData.[GetType]().IsArray Then
			Dim dataString As String = String.Empty
			Dim dataStringLen As Integer = 10
			Dim arr As Array = DirectCast(tagData, Array)
			If dataStringLen > arr.Length Then
				dataStringLen = arr.Length
			End If
			For i As Integer = 0 To dataStringLen - 1
				dataString += arr.GetValue(i).ToString()
				If i < (dataStringLen - 1) Then
					dataString += ", "
				End If
			Next
			If dataStringLen < arr.Length Then
				dataString += "..."
			End If
			lvi.SubItems.Add(dataString)
		Else
			lvi.SubItems.Add(tagData.ToString())
		End If
	End Sub

	#End Region


	#Region "Add tag"

	Private Sub bAddTag_Click(sender As Object, e As EventArgs)
		Dim dlg As New TagAddForm()
		If dlg.ShowDialog() <> System.Windows.Forms.DialogResult.OK Then
			Return
		End If

		Dim tagId As UShort = dlg.TagId

		' add tag to file
		Dim tagIndex As Integer = -1
		Dim tagData As Object = Nothing
		Select Case dlg.TagDataType
			Case TiffTagDataType.Ascii
				tagData = dlg.StringValue
				Exit Select

			Case TiffTagDataType.[Short]
				tagData = CUShort(dlg.IntegerValue)
				Exit Select
			Case TiffTagDataType.SShort
				tagData = CShort(dlg.IntegerValue)
				Exit Select

			Case TiffTagDataType.[Long]
				tagData = CUInt(dlg.IntegerValue)
				Exit Select
			Case TiffTagDataType.SLong
				tagData = CInt(dlg.IntegerValue)
				Exit Select

			Case TiffTagDataType.Float
				tagData = CSng(dlg.DoubleValue)
				Exit Select
			Case TiffTagDataType.[Double]
				tagData = dlg.DoubleValue
				Exit Select

			Case TiffTagDataType.Rational
				tagData = New Rational(CUInt(dlg.NumeratorValue), CUInt(dlg.DenominatorValue))
				Exit Select
			Case TiffTagDataType.SRational
				tagData = New SRational(CInt(dlg.NumeratorValue), CUInt(dlg.DenominatorValue))
				Exit Select
		End Select
		Dim tagsCount As Integer = _tiffPage.Tags.Count
		Try
			_tiffPage.Tags.Add(tagId, tagData)
			tagIndex = _tiffPage.Tags.Count - 1
		Catch ex As ArgumentException
			MessageBox.Show(ex.Message, "Add tag")
			Return
		End Try
		Dim tag As TiffTag = _tiffPage.Tags(tagIndex)

		' add/update tag info to list
		If tagsCount = tagIndex Then
			' new tag has been added
			AddTagDataToList(_tiffLvg, tag)
		Else
			' tag has been updated
			Dim item As ListViewItem = tagInfoList.Items(tagIndex)
			item.SubItems(3).Text = tag.Data.ToString()
		End If
	End Sub

	#End Region


	#Region "Modify tag"

	Private Sub ModifyTag(item As ListViewItem)
		If item Is Nothing Then
			Return
		End If
		If item.Tag Is Nothing Then
			Return
		End If

		Dim tag As TiffTag = DirectCast(item.Tag, TiffTag)
		If tag.IsReadonly Then
			MessageBox.Show("This tag is readonly.", "Modify tag")
			Return
		End If

		Dim tagId As UShort = tag.Id, tagDataType As UShort = CUShort(tag.Type)

		' create the update dialog
		Dim dlg As New TagModifyForm(tagDataType)
		' initialize tag value
		Dim referencedDataType As Type = tag.Data.[GetType]()
		If referencedDataType Is GetType(String) Then
			dlg.StringValue = DirectCast(tag.Data, String)
		ElseIf referencedDataType Is GetType(UShort) Then
			dlg.IntegerValue = CInt(CUShort(tag.Data))
		ElseIf referencedDataType Is GetType(Short) Then
			dlg.IntegerValue = CInt(CShort(tag.Data))
		ElseIf referencedDataType Is GetType(UInteger) Then
			dlg.IntegerValue = CInt(CUInt(tag.Data))
		ElseIf referencedDataType Is GetType(Integer) Then
			dlg.IntegerValue = CInt(tag.Data)
		ElseIf referencedDataType Is GetType(Single) Then
			dlg.DoubleValue = CSng(tag.Data)
		ElseIf referencedDataType Is GetType(Double) Then
			dlg.DoubleValue = CDbl(tag.Data)
		ElseIf referencedDataType Is GetType(Rational) Then
			Dim rational As Rational = DirectCast(tag.Data, Rational)
			dlg.NumeratorValue = CInt(rational.Numerator)
			dlg.DenominatorValue = CInt(rational.Denominator)
		ElseIf referencedDataType Is GetType(SRational) Then
			Dim srational As SRational = DirectCast(tag.Data, SRational)
			dlg.NumeratorValue = srational.Numerator
			dlg.DenominatorValue = CInt(srational.Denominator)
		Else
			MessageBox.Show("This demo does not allow to modify tags with arrays.", "Modify tag")
			Return
		End If

		' show dialog
		If dlg.ShowDialog() <> System.Windows.Forms.DialogResult.OK Then
			Return
		End If

		' change tag value
		Dim tagData As Object = Nothing
		Select Case tagDataType
			Case CInt(TiffTagDataType.Ascii)
				tagData = dlg.StringValue
				Exit Select

			Case CInt(TiffTagDataType.[Short])
				tagData = CUShort(dlg.IntegerValue)
				Exit Select
			Case CInt(TiffTagDataType.SShort)
				tagData = CShort(dlg.IntegerValue)
				Exit Select

			Case CInt(TiffTagDataType.[Long])
				tagData = CUInt(dlg.IntegerValue)
				Exit Select
			Case CInt(TiffTagDataType.SLong)
				tagData = CInt(dlg.IntegerValue)
				Exit Select

			Case CInt(TiffTagDataType.Float)
				tagData = CSng(dlg.DoubleValue)
				Exit Select
			Case CInt(TiffTagDataType.[Double])
				tagData = dlg.DoubleValue
				Exit Select

			Case CInt(TiffTagDataType.Rational)
				tagData = New Rational(CUInt(dlg.NumeratorValue), CUInt(dlg.DenominatorValue))
				Exit Select
			Case CInt(TiffTagDataType.SRational)
				tagData = New SRational(CInt(dlg.NumeratorValue), CUInt(dlg.DenominatorValue))
				Exit Select
		End Select
		tag.Data = tagData
		' change list item value
		item.SubItems(3).Text = tag.Data.ToString()
	End Sub

	Private Sub bModifyTag_Click(sender As Object, e As EventArgs)
		Dim item As ListViewItem = tagInfoList.FocusedItem
		ModifyTag(item)
	End Sub

	Private Sub tagInfoList_MouseDoubleClick(sender As Object, e As MouseEventArgs)
		Dim clickedItem As ListViewItem = tagInfoList.GetItemAt(5, e.Y)
		ModifyTag(clickedItem)
	End Sub

	#End Region


	#Region "Delete tag"

	Private Sub bDeleteTag_Click(sender As Object, e As EventArgs)
		Dim item As ListViewItem = tagInfoList.FocusedItem
		If item Is Nothing Then
			Return
		End If
		If item.Tag Is Nothing Then
			Return
		End If

		Dim tag As TiffTag = DirectCast(item.Tag, TiffTag)
		If tag.IsReadonly Then
			MessageBox.Show(String.Format("The ""{0}"" tag is readonly.", item.Text), "Delete tag")
			Return
		End If

		If MessageBox.Show(String.Format("Are you sure you want to delete the ""{0}"" tag?", item.Text), "Delete tag", MessageBoxButtons.OKCancel) <> System.Windows.Forms.DialogResult.OK Then
			Return
		End If

		' remove the tag from the tag collection
		_tiffPage.Tags.Remove(tag)
		' remove the tag info from the list
		tagInfoList.Items.Remove(item)
	End Sub

	#End Region

	#End Region

End Class
